package cn.edu.ncu.housinghub.service.impl;

import cn.edu.ncu.housinghub.entity.message.SystemMessage;
import cn.edu.ncu.housinghub.mapper.message.SystemMessageMapper;
import cn.edu.ncu.housinghub.service.SystemNotificationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 系统通知服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SystemNotificationServiceImpl implements SystemNotificationService {

    private final SimpMessagingTemplate messagingTemplate;
    private final SystemMessageMapper systemMessageMapper;

    @Override
    public void sendContractNotification(Long tenantId, Long landlordId, Long contractId, String houseTitle, String notificationType) {
        String title, content;

        switch (notificationType) {
            case "contract_created":
                title = "新的租赁合同";
                content = String.format("房东为您的房源【%s】创建了租赁合同，请及时查看并签署。", houseTitle);
                sendNotificationToUser(tenantId, title, content, "contract", notificationType, contractId,
                    null, "/contract/tenant", "查看合同");

                title = "合同已创建";
                content = String.format("您为房源【%s】创建的租赁合同已发送给租客，等待对方签署。", houseTitle);
                sendNotificationToUser(landlordId, title, content, "contract", notificationType, contractId,
                    null, "/contract/landlord", "查看合同");
                break;

            case "contract_signed":
                title = "合同签署完成";
                content = String.format("房源【%s】的租赁合同已双方签署完成，租赁关系正式生效。", houseTitle);
                sendNotificationToUser(tenantId, title, content, "success", notificationType, contractId,
                    null, "/contract/tenant", "查看合同");
                sendNotificationToUser(landlordId, title, content, "success", notificationType, contractId,
                    null, "/contract/landlord", "查看合同");
                break;

            case "contract_rejected":
                title = "合同被拒绝";
                content = String.format("房源【%s】的租赁合同被对方拒绝，您可以重新协商条款。", houseTitle);
                sendNotificationToUser(landlordId, title, content, "warning", notificationType, contractId,
                    null, "/contract/landlord", "重新协商");
                break;
        }
    }

    @Override
    public void sendAppointmentNotification(Long landlordId, Long tenantId, String houseTitle, String appointmentTime, String notificationType) {
        String title, content;
        
        switch (notificationType) {
            case "appointment_created":
                title = "新的看房预约";
                content = String.format("有租客预约看房【%s】，预约时间：%s，请及时处理。", houseTitle, appointmentTime);
                sendNotificationToUser(landlordId, title, content, "appointment");
                
                title = "预约申请已提交";
                content = String.format("您的看房预约【%s】已提交，预约时间：%s，请等待房东确认。", houseTitle, appointmentTime);
                sendNotificationToUser(tenantId, title, content, "info");
                break;
                
            case "appointment_confirmed":
                title = "预约已确认";
                content = String.format("您的看房预约【%s】已被确认，预约时间：%s，请准时到达。", houseTitle, appointmentTime);
                sendNotificationToUser(tenantId, title, content, "success");
                break;
                
            case "appointment_cancelled":
                title = "预约已取消";
                content = String.format("房源【%s】的看房预约（%s）已被取消。", houseTitle, appointmentTime);
                sendNotificationToUser(tenantId, title, content, "warning");
                sendNotificationToUser(landlordId, title, content, "info");
                break;
        }
    }

    @Override
    public void sendHouseVerificationNotification(Long landlordId, String houseTitle, String status, String reason) {
        String title, content;
        
        if ("approved".equals(status)) {
            title = "房源审核通过";
            content = String.format("您发布的房源【%s】已通过审核，现在可以在房源列表中查看。", houseTitle);
            sendNotificationToUser(landlordId, title, content, "success");
        } else {
            title = "房源审核未通过";
            content = String.format("您发布的房源【%s】审核未通过。原因：%s", houseTitle, reason != null ? reason : "不符合平台规范");
            sendNotificationToUser(landlordId, title, content, "warning");
        }
    }

    @Override
    public void sendAgentVerificationNotification(Long userId, String status, String reason) {
        String title, content;
        
        if ("approved".equals(status)) {
            title = "中介认证通过";
            content = "恭喜！您的中介资质认证已通过，现在可以开始代理房源业务。";
            sendNotificationToUser(userId, title, content, "success");
        } else {
            title = "中介认证未通过";
            content = String.format("您的中介资质认证未通过。原因：%s", reason != null ? reason : "资质材料不符合要求");
            sendNotificationToUser(userId, title, content, "warning");
        }
    }

    @Override
    public void sendMaintenanceNotification(Long landlordId, Long tenantId, String houseTitle, String description, String notificationType) {
        String title, content;
        
        switch (notificationType) {
            case "maintenance_request":
                title = "新的维修请求";
                content = String.format("房源【%s】有新的维修请求：%s，请及时处理。", houseTitle, description);
                sendNotificationToUser(landlordId, title, content, "maintenance");
                
                title = "维修请求已提交";
                content = String.format("您的维修请求已提交，房源：【%s】，问题描述：%s", houseTitle, description);
                sendNotificationToUser(tenantId, title, content, "info");
                break;
                
            case "maintenance_completed":
                title = "维修已完成";
                content = String.format("房源【%s】的维修工作已完成：%s", houseTitle, description);
                sendNotificationToUser(tenantId, title, content, "success");
                break;
        }
    }

    @Override
    public void sendCheckoutNotification(Long landlordId, Long tenantId, String houseTitle, String notificationType) {
        String title, content;
        
        switch (notificationType) {
            case "checkout_request":
                title = "新的退租申请";
                content = String.format("房源【%s】有新的退租申请，请及时处理。", houseTitle);
                sendNotificationToUser(landlordId, title, content, "checkout");
                
                title = "退租申请已提交";
                content = String.format("您的退租申请已提交，房源：【%s】，请等待房东处理。", houseTitle);
                sendNotificationToUser(tenantId, title, content, "info");
                break;
                
            case "checkout_approved":
                title = "退租申请已批准";
                content = String.format("您的退租申请已被批准，房源：【%s】，请按约定时间办理退租手续。", houseTitle);
                sendNotificationToUser(tenantId, title, content, "success");
                break;
                
            case "checkout_rejected":
                title = "退租申请被拒绝";
                content = String.format("您的退租申请被拒绝，房源：【%s】，请联系房东了解详情。", houseTitle);
                sendNotificationToUser(tenantId, title, content, "warning");
                break;
        }
    }

    @Override
    public void sendSystemAnnouncement(String title, String content, List<Long> targetUserIds) {
        if (targetUserIds == null || targetUserIds.isEmpty()) {
            // 发送给所有用户（通过广播）
            sendBroadcastNotification(title, content, "announcement");
        } else {
            // 发送给指定用户
            for (Long userId : targetUserIds) {
                sendNotificationToUser(userId, title, content, "announcement");
            }
        }
    }

    @Override
    public void sendHouseExpirationReminder(Long landlordId, String houseTitle, int daysLeft) {
        String title = "房源即将到期提醒";
        String content = String.format("您发布的房源【%s】将在%d天后到期，请及时续期以免影响展示。", houseTitle, daysLeft);
        sendNotificationToUser(landlordId, title, content, "warning");
    }

    @Override
    public void sendRentReminder(Long tenantId, String houseTitle, BigDecimal amount, String dueDate) {
        String title = "租金缴费提醒";
        String content = String.format("房源【%s】的租金￥%.2f将于%s到期，请及时缴费。", houseTitle, amount, dueDate);
        sendNotificationToUser(tenantId, title, content, "payment");
    }

    /**
     * 发送通知给指定用户
     */
    private void sendNotificationToUser(Long userId, String title, String content, String type) {
        sendNotificationToUser(userId, title, content, type, null, null, null, null, null);
    }

    /**
     * 发送通知给指定用户（完整版本）
     */
    private void sendNotificationToUser(Long userId, String title, String content, String type,
                                       String subType, Long relatedId, String relatedData,
                                       String actionUrl, String actionText) {
        try {
            // 创建系统消息对象
            SystemMessage systemMessage = new SystemMessage();
            systemMessage.setUserId(userId);
            systemMessage.setTitle(title);
            systemMessage.setContent(content);
            systemMessage.setType(type);
            systemMessage.setSubType(subType);
            systemMessage.setRelatedId(relatedId);
            systemMessage.setRelatedData(relatedData);
            systemMessage.setIsRead(false);
            systemMessage.setCreateTime(LocalDateTime.now());
            systemMessage.setIsDeleted(false);
            systemMessage.setPriority(getPriorityByType(type));
            systemMessage.setActionUrl(actionUrl);
            systemMessage.setActionText(actionText);

            // 保存到数据库
            systemMessageMapper.saveMessage(systemMessage);

            // 创建WebSocket通知对象
            Map<String, Object> notification = createNotification(title, content, type);
            notification.put("messageId", systemMessage.getMessageId());
            notification.put("actionUrl", actionUrl);
            notification.put("actionText", actionText);

            // 通过WebSocket发送实时通知
            messagingTemplate.convertAndSend("/user/" + userId + "/queue/notification", notification);

            log.info("发送系统通知给用户 {}: {}", userId, title);

        } catch (Exception e) {
            log.error("发送系统通知失败，用户ID: {}, 标题: {}", userId, title, e);
        }
    }

    /**
     * 根据消息类型获取优先级
     */
    private Integer getPriorityByType(String type) {
        switch (type) {
            case "contract":
            case "payment":
                return 2; // 紧急
            case "appointment":
            case "maintenance":
            case "checkout":
                return 1; // 重要
            default:
                return 0; // 普通
        }
    }

    /**
     * 发送广播通知
     */
    private void sendBroadcastNotification(String title, String content, String type) {
        try {
            Map<String, Object> notification = createNotification(title, content, type);
            
            // 通过WebSocket发送广播通知
            messagingTemplate.convertAndSend("/topic/announcement", notification);
            
            log.info("发送广播通知: {}", title);
            
        } catch (Exception e) {
            log.error("发送广播通知失败，标题: {}", title, e);
        }
    }

    /**
     * 创建通知对象
     */
    private Map<String, Object> createNotification(String title, String content, String type) {
        Map<String, Object> notification = new HashMap<>();
        notification.put("title", title);
        notification.put("content", content);
        notification.put("type", type);
        notification.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        notification.put("read", false);
        return notification;
    }
}
